package com.sajus.web.billing.admin.action;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.sajus.billing.client.delegate.BusinessDelegateFactory;
import com.sajus.billing.client.dto.AccountDTO;
import com.sajus.billing.client.dto.BillDTO;
import com.sajus.billing.client.dto.BillItemDTO;
import com.sajus.billing.client.dto.ServiceDTO;
import com.sajus.billing.client.dto.UsageItemLineDTO;

/**
 * Acts as a Struts 2 controller that responds
 * to a user action by setting the value
 * of the Message model class, and returns a String 
 * result.
 * @author Bruce Phillips
 *
 */
public class BillingInvoiceAction extends ActionSupport {

	private static final long serialVersionUID = 1L;
	private final int RECURRING = 1;
	private final int USAGE = 2;
	
	private Date startDate;
	private Date endDate;
	private int level = 0;
	
	private double total;
	
	/**
	 * The model class that stores the message
	 * to display in the view.
	 */
	private AccountDTO account;
	
	private List<AccountDTO> accounts;
	
	private BillDTO bill;
	
	
	/*
	 * Creates the MessageStore model object and 
	 * returns success.  The MessageStore model
	 * object will be available to the view.
	 * (non-Javadoc)
	 * @see com.opensymphony.xwork2.ActionSupport#execute()
	 */
	public String execute() throws Exception {
		
		String paramValue = ServletActionContext.getRequest().getParameter("accountId");
		
		if ( paramValue != null ) {
			
			Integer id = new Integer( Integer.parseInt( paramValue ) );
			this.account = BusinessDelegateFactory.getInstance().getAccountManager().getAccount( id );
			
			List<ServiceDTO> fullServices = BusinessDelegateFactory.getInstance()
					.getServiceTypeManager().getServices( this.account );
			
			List<ServiceDTO> recurring = new ArrayList<ServiceDTO>();
			
			for ( ServiceDTO service : fullServices ){
				if ( service.getOffering().getServiceType() != null 
						&& service.getOffering().getServiceType().getType() != null ){
					if ( service.getOffering().getServiceType().getType().intValue() == RECURRING ) {
						recurring.add( service );
					} 
				}
			}
			
			this.account.setRecurring( recurring );
			
			this.bill = BusinessDelegateFactory.getInstance().getAccountManager().getBill( this.account );
			total = this.bill.getAmountDue();
			ArrayList<UsageItemLineDTO> usageList = new ArrayList<UsageItemLineDTO>();
			
			if ( this.bill.getItems() != null ) {
				for ( BillItemDTO item : this.bill.getItems() ) {
					if ( item.getUsageLineItems() != null ){
						for ( UsageItemLineDTO usageLine : item.getUsageLineItems() ){
							usageList.add( usageLine );
						}
					}
				}
			}
			
			this.account.setUsage( usageList );
			
			this.startDate = this.bill.getBillingPeriodStart();
			this.endDate = this.bill.getBillingPeriodEnd();
			
			setChildServices( this.account, 0 );
			
		} else {
			return ERROR;
		}
		
		System.out.println( "total = " + total );
		
		return SUCCESS;
	}
	
	private int setChildServices( AccountDTO acc, int index ) {
		
		if ( acc == null ){
			return index;
		} else {
			index++;
			if ( this.accounts == null ){
				this.accounts = new ArrayList<AccountDTO>();
			}
		}
		
		this.accounts.add( acc );
		List<AccountDTO> children = acc.getChildrenAccounts();
		
		try {
			if ( children != null ){
				for ( AccountDTO child : children ) {
					
					int tmp = setChildServices( child, index );
					if ( tmp > index ){
						index = tmp;
					}
					
					List<ServiceDTO> fullServices = BusinessDelegateFactory.getInstance()
							.getServiceTypeManager().getServices( child );
					
					List<ServiceDTO> c_recurring = new ArrayList<ServiceDTO>();
					
					
					for ( ServiceDTO service : fullServices ){
						if ( service.getOffering().getServiceType() != null 
								&& service.getOffering().getServiceType().getType() != null ){
							if ( service.getOffering().getServiceType().getType().intValue() == RECURRING ) {
								c_recurring.add( service );
								
							} 
						}
					}
					
					child.setRecurring( c_recurring );
					BillDTO bill = BusinessDelegateFactory.getInstance().getAccountManager().getBill( child );
//					total = total + bill.getAmountDue();
					
					ArrayList<UsageItemLineDTO> usageList = new ArrayList<UsageItemLineDTO>();
					
					if ( bill.getItems() != null ) {
						for ( BillItemDTO item : bill.getItems() ) {
							if ( item.getUsageLineItems() != null ){
								for ( UsageItemLineDTO usageLine : item.getUsageLineItems() ){
									usageList.add( usageLine );
								}
							}
						}
					}
					
					child.setUsage( usageList );
					System.out.println( "total = " +total );
				}
			}
		} catch ( Exception e ) {
			e.printStackTrace();
		}
		
		return index;
	}


	public String getStartDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
		
		return sdf.format(startDate);
	}



	public String getEndDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
		return sdf.format( endDate );
	}


	public int getLevel() {
		return level;
	}


	public void setLevel(int level) {
		this.level = level;
	}


	public AccountDTO getAccount() {
		return account;
	}


	public void setAccount(AccountDTO account) {
		this.account = account;
	}


	public BillDTO getBill() {
		return bill;
	}


	public void setBill(BillDTO bill) {
		this.bill = bill;
	}


	public List<AccountDTO> getAccounts() {
		return accounts;
	}


	public void setAccounts(List<AccountDTO> accounts) {
		this.accounts = accounts;
	}


	public double getTotal() {
		return total;
	}


	public void setTotal(double total) {
		this.total = total;
	}
	
}
